package code

type Option interface {
	Apply(*Options)
}

type Options struct {
	ExtraImports    bool
	ExtraConstants  bool
	ExtraStructs    bool
	ExtraInterfaces bool
	ExtraFunctions  bool
}

func NewOptions(opts ...Option) *Options {
	o := &Options{}
	for _, opt := range opts {
		opt.Apply(o)
	}
	return o
}

type fnOption struct {
	fn func(*Options)
}

func (f *fnOption) Apply(options *Options) {
	f.fn(options)
}

func WithImports() Option {
	return &fnOption{
		fn: func(options *Options) {
			options.ExtraImports = true
		},
	}
}
func WithConstants() Option {
	return &fnOption{
		fn: func(options *Options) {
			options.ExtraConstants = true
		},
	}
}
func WithStructs() Option {
	return &fnOption{
		fn: func(options *Options) {
			options.ExtraStructs = true
		},
	}
}
func WithInterfaces() Option {
	return &fnOption{
		fn: func(options *Options) {
			options.ExtraInterfaces = true
		},
	}
}
func WithFunctions() Option {
	return &fnOption{
		fn: func(options *Options) {
			options.ExtraFunctions = true
		},
	}
}
